package com.work.demo.controller;

import cn.hutool.core.util.IdUtil;
import org.apache.commons.lang.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName : IndexController
 * @Description :
 * @Author : LinYa
 * @Date: 2021/12/15  13:43
 */
@RestController
public class IndexController {

	@Autowired
	private Redisson redisson;

	@Autowired
	private StringRedisTemplate redisTemplate;


	/**
	 * 基于redis.setNx实现分布式锁
	 */
	@GetMapping("/deduct_stock")
	public String deductStock() {
		String lockKey = "product_lock134";
		String uuid = IdUtil.simpleUUID();
		try {
			//setNx加锁
			Boolean flag = redisTemplate.opsForValue().setIfAbsent(lockKey, uuid, 10, TimeUnit.SECONDS);

			//加锁失败直接返回
			if (!flag) {
				return "error";
			}
			//获取redis现在的库存总数
			String stockStr = redisTemplate.opsForValue().get("stock");

			//如果库存key不存在，这初始化库存
			if (StringUtils.isBlank(stockStr)) {
				redisTemplate.opsForValue().set("stock", "50");
			} else {
				//类型转换
				int stock = Integer.parseInt(stockStr);
				if (stock > 0) {
					//扣减库存
					int nowStock = stock - 1;
					//设置新的库存
					redisTemplate.opsForValue().set("stock", nowStock + "");
					System.out.println("扣减后的库存：" + nowStock);
				} else {
					System.out.println("商品已卖完");
				}
			}
		} finally {
			//释放锁
			if (uuid.equals(redisTemplate.opsForValue().get(lockKey))) {
				redisTemplate.delete(lockKey);
			}
		}

		return "成功";
	}


	/**
	 * 基于redisson实现分布式锁
	 */
	@GetMapping("/redisson_lock")
	public String redissonLock() {
		String lockKey = "product_lock";
		RLock redissonLock = redisson.getLock(lockKey);
		try {

			// 加锁，实现锁续命的功能
			redissonLock.lock();

			int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock"));

			if (stock > 0) {
				int nowStock = stock - 1;
				redisTemplate.opsForValue().set("stock", nowStock + "");
				System.out.println("扣减后的库存：" + nowStock);
			} else {
				System.out.println("商品已卖完");
			}

		} finally {
			redissonLock.unlock();
		}

		return "成功";
	}

	@GetMapping("/teacher_stock")
	public String teacherStock() {
		String lockKey = "product_101";
        /*Boolean result = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, "zhuge"); //jedis.setnx(k,v)
        stringRedisTemplate.expire(lockKey, 10, TimeUnit.SECONDS);*/

		String clientId = IdUtil.simpleUUID();
		Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);
		if (!result) {
			System.out.println("获取锁失败！！！！！");
			return "error_code";
		}

        /* 读写锁示例
        RReadWriteLock readWriteLock = redisson.getReadWriteLock(lockKey);
        RLock rLock = readWriteLock.readLock();
        RLock wLock = readWriteLock.writeLock();
        */

//		RLock redissonLock = redisson.getLock(lockKey);
		try {
            /*rLock.lock();
            wLock.lock();*/
//			redissonLock.lock();  //setIfAbsent(lockKey, clientId, 30, TimeUnit.SECONDS);
			int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock")); // jedis.get("stock")
			if (stock > 0) {
				int realStock = stock - 1;
				redisTemplate.opsForValue().set("stock", realStock + ""); // jedis.set(key,value)
				System.out.println("扣减成功，剩余库存:" + realStock);
			} else {
				System.out.println("扣减失败，库存不足");
			}
		} finally {
            /*rLock.unlock();
            wLock.unlock();*/
//			redissonLock.unlock();
			if (clientId.equals(redisTemplate.opsForValue().get(lockKey))) {
				redisTemplate.delete(lockKey);
			}
		}

		return "end";
	}

}
